import React, {
  FC,
  ReactElement,
  useCallback,
  useRef,
  forwardRef,
  useImperativeHandle,
} from "react";
import { useState } from "react";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import styled from "styled-components";
import { Button } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { FlexDiv } from "../BUI";

interface IProps {
  onCrop: (file: any) => void;
  ref?: any;
}

const ImageCropper: FC<IProps> = forwardRef(({ onCrop }, ref): ReactElement => {
  const cropperRef = useRef<HTMLImageElement>(null);
  const fileInput = useRef<HTMLInputElement>(null);
  const [image, setImage] = useState<any>("");

  const handleSelectFile = useCallback(e => {
    e.preventDefault();
    let files = null;
    if (e.dataTransfer) {
      files = e.dataTransfer.files;
    } else if (e.target) {
      files = e.target.files;
    }
    if (!files) return;
    const reader = new FileReader();
    reader.onload = () => {
      setImage(reader.result as any);
    };
    reader.readAsDataURL(files[0]);
  }, []);

  const cancelCrop = useCallback(() => {
    setImage("");
    //不重置input的value 下次打开同一个图片不会触发change事件
    fileInput.current && (fileInput.current.value = "");
  }, []);

  const handleCrop = useCallback(() => {
    const imageElement: any = cropperRef?.current;
    const cropper: any = imageElement?.cropper;
    const file = cropper.getCroppedCanvas().toDataURL();
    onCrop(file);
    cancelCrop();
  }, [cropperRef, onCrop, cancelCrop]);

  useImperativeHandle(ref, () => fileInput.current, [fileInput]);

  return (
    <React.Fragment>
      <UploadBox>
        <PlusOutlined />
        上传
        <input
          accept='.png, .jpg, .jpeg'
          ref={fileInput}
          type='file'
          onChange={handleSelectFile}
        />
      </UploadBox>
      <Container show={image}>
        <Cropper
          src={image}
          style={{ height: 400, width: "100%" }}
          initialAspectRatio={1}
          guides={false}
          ref={cropperRef}
        />
        <FlexDiv space='10px' height='100px' justify='center' items='center'>
          <Button onClick={handleCrop} type='primary'>
            裁剪
          </Button>
          <Button onClick={cancelCrop} type='dashed'>
            取消
          </Button>
        </FlexDiv>
      </Container>
    </React.Fragment>
  );
});

export default ImageCropper;

const Container = styled.div<{ show: boolean }>`
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #fff;
  width: 500px;
  height: 500px;
  box-shadow: 1px 0 5px 0 #cccccc;
  border-radius: 5px;
  opacity: ${props => (props.show ? 1 : 0)};
  z-index: ${props => (props.show ? 9 : -1)};
  transition-property: opacity;
  transition-duration: 0.4s;
  transition-timing-function: ease-in;
  overflow: hidden;
`;

const UploadBox = styled.div`
  width: 100px;
  height: 100px;
  border-radius: 3px;
  background-color: #f9f9f9;
  border: 1px dashed var(--border-color);
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  padding: 20px;
  align-items: center;
  position: relative;

  input {
    cursor: pointer;
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
  }
`;
